﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace ImageShaperLib.Tools
{
    

    /// <summary>
    /// CuttingRectangle的摘要说明（画一个可拖放大小的矩形选框）
    /// </summary>
    public class CuttingRectangle  
    {
         private enum PosSizableRect
         {
             UpMiddle,
             LeftMiddle,
             LeftBottom,
             LeftUp,
             RightUp,
             RightMiddle,
             RightBottom,
             BottomMiddle,
             None
         };

        private System.Windows.Forms.Form mDocForm;
        public  System.Drawing.Rectangle rect;
        public bool allowDeformingDuringMovement = false;
        private bool mIsClick = false;
        public static bool mMove = false;
        private int oldX;
        private int oldY;
        private int sizeNodeRect = 5;
        private Bitmap mBmp = null;
        private PosSizableRect nodeSelected = PosSizableRect.None;
        private int angle = 30;



         public CuttingRectangle()
         {

         }


         public CuttingRectangle(System.Drawing.Rectangle r)
        {
            rect = r;
            mIsClick = false;
        }
         public void Draw(Graphics g)
         {
             g.DrawRectangle(new Pen(Color.Red), rect);

             foreach (PosSizableRect pos in Enum.GetValues(typeof(PosSizableRect)))
             {
                 g.DrawRectangle(new Pen(Color.Red), GetRect(pos));
             }
         }

         public void SetBitmapFile(string filename)
         {
             this.mBmp = new Bitmap(filename);
         }

         public void SetBitmap(Bitmap bmp)
         {
             this.mBmp = bmp;
         }

         public void SetPictureBox(System.Windows.Forms.Form form)
         {
             this.mDocForm = form;
             mDocForm.MouseDown += new MouseEventHandler(mDocForm_MouseDown);
             mDocForm.MouseUp += new MouseEventHandler(mDocForm_MouseUp);
             mDocForm.MouseMove += new MouseEventHandler(mDocForm_MouseMove);
             mDocForm.Paint += new PaintEventHandler(mDocForm_Paint);
         }

         private void mDocForm_Paint(object sender, PaintEventArgs e)
         {
             MessageBox.Show("hee");
             try
             {
                 Draw(e.Graphics);
             }
             catch (Exception exp)
             {
                 System.Console.WriteLine(exp.Message);
             }

         }

         private void mDocForm_MouseDown(object sender, MouseEventArgs e)
         {
             MessageBox.Show("MouseDown");
             mIsClick = true;

             nodeSelected = PosSizableRect.None;
             nodeSelected = GetNodeSelectable(e.Location);

             if (rect.Contains(new Point(e.X, e.Y)))
             {
                 mMove = true;
             }
             oldX = e.X;
             oldY = e.Y;
         }

         private void mDocForm_MouseUp(object sender, MouseEventArgs e)
         {
             mIsClick = false;
             mMove = false;
         }

         private void mDocForm_MouseMove(object sender, MouseEventArgs e)
         {
             ChangeCursor(e.Location);
             if (mIsClick == false)
             {
                 return;
             }

             System.Drawing.Rectangle backupRect = rect;

             switch (nodeSelected)
             {
                 case PosSizableRect.LeftUp:
                     rect.X += e.X - oldX;
                     rect.Width -= e.X - oldX;
                     rect.Y += e.Y - oldY;
                     rect.Height -= e.Y - oldY;
                     break;
                 case PosSizableRect.LeftMiddle:
                     rect.X += e.X - oldX;
                     rect.Width -= e.X - oldX;
                     break;
                 case PosSizableRect.LeftBottom:
                     rect.Width -= e.X - oldX;
                     rect.X += e.X - oldX;
                     rect.Height += e.Y - oldY;
                     break;
                 case PosSizableRect.BottomMiddle:
                     rect.Height += e.Y - oldY;
                     break;
                 case PosSizableRect.RightUp:
                     rect.Width += e.X - oldX;
                     rect.Y += e.Y - oldY;
                     rect.Height -= e.Y - oldY;
                     break;
                 case PosSizableRect.RightBottom:
                     rect.Width += e.X - oldX;
                     rect.Height += e.Y - oldY;
                     break;
                 case PosSizableRect.RightMiddle:
                     rect.Width += e.X - oldX;
                     break;

                 case PosSizableRect.UpMiddle:
                     rect.Y += e.Y - oldY;
                     rect.Height -= e.Y - oldY;
                     break;

                 default:
                     if (mMove)
                     {
                         //rect.X = rect.X + e.X - oldX;
                         //rect.Y = rect.Y + e.Y - oldY;
                     }
                     break;
             }
             oldX = e.X;
             oldY = e.Y;

             if (rect.Width < 5 || rect.Height < 5)
             {
                 rect = backupRect;
             }

             TestIfRectInsideArea();

             mDocForm.Invalidate();
         }

         private void TestIfRectInsideArea()
         {
             // 检测矩形是否还在Area 中 
             if (rect.X < 0) rect.X = 0;
             if (rect.Y < 0) rect.Y = 0;
             if (rect.Width <= 0) rect.Width = 1;
             if (rect.Height <= 0) rect.Height = 1;

             if (rect.X + rect.Width > mDocForm.Width)
             {
                 rect.Width = mDocForm.Width - rect.X - 1; // -1 将继续显示
                 if (allowDeformingDuringMovement == false)
                 {
                     mIsClick = false;
                 }
             }
             if (rect.Y + rect.Height > mDocForm.Height)
             {
                 rect.Height = mDocForm.Height - rect.Y - 1;// -1 将继续显示
                 if (allowDeformingDuringMovement == false)
                 {
                     mIsClick = false;
                 }
             }
         }

         private System.Drawing.Rectangle CreateRectSizableNode(int x, int y)
         {
             return new System.Drawing.Rectangle(x - sizeNodeRect / 2, y - sizeNodeRect / 2, sizeNodeRect, sizeNodeRect);
         }

         private System.Drawing.Rectangle GetRect(PosSizableRect p)
         {
             switch (p)
             {
                 case PosSizableRect.LeftUp:
                     return CreateRectSizableNode(rect.X, rect.Y);

                 case PosSizableRect.LeftMiddle:
                     return CreateRectSizableNode(rect.X, rect.Y + +rect.Height / 2);

                 case PosSizableRect.LeftBottom:
                     return CreateRectSizableNode(rect.X, rect.Y + rect.Height);

                 case PosSizableRect.BottomMiddle:
                     return CreateRectSizableNode(rect.X + rect.Width / 2, rect.Y + rect.Height);

                 case PosSizableRect.RightUp:
                     return CreateRectSizableNode(rect.X + rect.Width, rect.Y);

                 case PosSizableRect.RightBottom:
                     return CreateRectSizableNode(rect.X + rect.Width, rect.Y + rect.Height);

                 case PosSizableRect.RightMiddle:
                     return CreateRectSizableNode(rect.X + rect.Width, rect.Y + rect.Height / 2);

                 case PosSizableRect.UpMiddle:
                     return CreateRectSizableNode(rect.X + rect.Width / 2, rect.Y);
                 default:
                     return new System.Drawing.Rectangle();
             }
         }

         private PosSizableRect GetNodeSelectable(Point p)
         {
             foreach (PosSizableRect r in Enum.GetValues(typeof(PosSizableRect)))
             {
                 if (GetRect(r).Contains(p))
                 {
                     return r;
                 }
             }
             return PosSizableRect.None;
         }

         private void ChangeCursor(Point p)
         {
             mDocForm.Cursor = GetCursor(GetNodeSelectable(p));
         }

         /// <summary>
         /// 获取光标样式
         /// </summary>
         /// <param name="p"></param>
         /// <returns></returns>
         private Cursor GetCursor(PosSizableRect p)
         {
             switch (p)
             {
                 case PosSizableRect.LeftUp:
                     return Cursors.SizeNWSE;

                 case PosSizableRect.LeftMiddle:
                     return Cursors.SizeWE;

                 case PosSizableRect.LeftBottom:
                     return Cursors.SizeNESW;

                 case PosSizableRect.BottomMiddle:
                     return Cursors.SizeNS;

                 case PosSizableRect.RightUp:
                     return Cursors.SizeNESW;

                 case PosSizableRect.RightBottom:
                     return Cursors.SizeNWSE;

                 case PosSizableRect.RightMiddle:
                     return Cursors.SizeWE;

                 case PosSizableRect.UpMiddle:
                     return Cursors.SizeNS;
                 default:
                     return Cursors.Default;
             }
         }

    }
 }
